package com.youlai.boot.factory.controller;

import com.youlai.boot.factory.model.vo.EmployeePaymentStatusVO;
import com.youlai.boot.factory.model.vo.EmployeeSalaryVO;
import com.youlai.boot.factory.model.vo.MonthlySalaryVO;
import com.youlai.boot.factory.model.vo.WorkReportDetailVO;
import com.youlai.boot.factory.service.WorkReportService;
import com.youlai.boot.factory.service.SalaryPaymentRecordService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.youlai.boot.factory.model.form.WorkReportForm;
import com.youlai.boot.factory.model.query.WorkReportQuery;
import com.youlai.boot.factory.model.vo.WorkReportVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youlai.boot.common.result.PageResult;
import com.youlai.boot.common.result.Result;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;

import java.util.List;

/**
 * 报工单前端控制层
 *
 * @author youlaitech
 * @since 2025-10-13 13:30
 */
@Tag(name = "报工单接口")
@RestController
@RequestMapping("/api/v1/work-report")
@RequiredArgsConstructor
public class WorkReportController  {

    private final WorkReportService workReportService;
    private final SalaryPaymentRecordService salaryPaymentRecordService;

    @Operation(summary = "报工单分页列表")
    @GetMapping("/page")
    @PreAuthorize("@ss.hasPerm('factory:work-report:query')")
    public PageResult<WorkReportVO> getWorkReportPage(WorkReportQuery queryParams ) {
        IPage<WorkReportVO> result = workReportService.getWorkReportPage(queryParams);
        return PageResult.success(result);
    }


    @Operation(summary = "查询我的报工单列表")
    @GetMapping("/myPage")
    @PreAuthorize("@ss.hasPerm('factory:work-report:query')")
    public PageResult<WorkReportVO> getMyWorkReportPage(WorkReportQuery queryParams ) {
        IPage<WorkReportVO> result = workReportService.getMyWorkReportPage(queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "新增报工单")
    @PostMapping()
    @PreAuthorize("@ss.hasPerm('factory:work-report:add')")
    public Result<Void> saveWorkReport(@RequestBody @Valid WorkReportForm formData ) {
        boolean result = workReportService.saveWorkReport(formData);
        return Result.judge(result);
    }

    @Operation(summary = "报工提交")
    @PostMapping("/submit")
    @PreAuthorize("@ss.hasPerm('factory:work-report:add')")
    public Result<Void> submitWorkReport(@RequestBody @Valid WorkReportForm formData ) {
        boolean result = workReportService.submitWorkReport(formData);
        return Result.judge(result);
    }

    @Operation(summary = "获取报工单表单数据")
    @GetMapping("/{id}/form")
    @PreAuthorize("@ss.hasPerm('factory:work-report:edit')")
    public Result<WorkReportForm> getWorkReportForm(
        @Parameter(description = "报工单ID") @PathVariable Long id
    ) {
        WorkReportForm formData = workReportService.getWorkReportFormData(id);
        return Result.success(formData);
    }


    @Operation(summary = "获取报工单详情信息")
    @GetMapping("/{id}/detail")
    @PreAuthorize("@ss.hasPerm('factory:work-report:edit')")
    public Result<WorkReportDetailVO> getWorkReportDetail(
            @Parameter(description = "报工单ID") @PathVariable Long id
    ) {
        WorkReportDetailVO formData = workReportService.getWorkReportDetail(id);
        return Result.success(formData);
    }

    @Operation(summary = "修改报工单")
    @PutMapping(value = "/{id}")
    @PreAuthorize("@ss.hasPerm('factory:work-report:edit')")
    public Result<Void> updateWorkReport(
            @Parameter(description = "报工单ID") @PathVariable Long id,
            @RequestBody @Validated WorkReportForm formData
    ) {
        boolean result = workReportService.updateWorkReport(id, formData);
        return Result.judge(result);
    }

    @Operation(summary = "删除报工单")
    @DeleteMapping("/{ids}")
    @PreAuthorize("@ss.hasPerm('factory:work-report:delete')")
    public Result<Void> deleteWorkReports(
        @Parameter(description = "报工单ID，多个以英文逗号(,)分割") @PathVariable String ids
    ) {
        boolean result = workReportService.deleteWorkReports(ids);
        return Result.judge(result);
    }

    @Operation(summary = "审核通过报工单")
    @PostMapping("/{id}/approve")
    @PreAuthorize("@ss.hasPerm('factory:work-report:audit')")
    public Result<Void> approveWorkReport(
        @Parameter(description = "报工单ID") @PathVariable Long id
    ) {
        boolean result = workReportService.approveWorkReport(id);
        return Result.judge(result);
    }

    @Operation(summary = "批量审核通过报工单")
    @PostMapping("/batch-approve")
    @PreAuthorize("@ss.hasPerm('factory:work-report:audit')")
    public Result<Void> batchApproveWorkReports(
        @RequestBody @Validated BatchAuditForm formData
    ) {
        boolean result = workReportService.batchApproveWorkReports(formData.getIds());
        return Result.judge(result);
    }

    @Operation(summary = "驳回报工单")
    @PostMapping("/{id}/reject")
    @PreAuthorize("@ss.hasPerm('factory:work-report:audit')")
    public Result<Void> rejectWorkReport(
        @Parameter(description = "报工单ID") @PathVariable Long id,
        @RequestBody @Validated RejectForm formData
    ) {
        boolean result = workReportService.rejectWorkReport(id, formData.getRejectReason());
        return Result.judge(result);
    }

    @Operation(summary = "批量驳回报工单")
    @PostMapping("/batch-reject")
    @PreAuthorize("@ss.hasPerm('factory:work-report:audit')")
    public Result<Void> batchRejectWorkReports(
        @RequestBody @Validated BatchRejectForm formData
    ) {
        boolean result = workReportService.batchRejectWorkReports(formData.getIds(), formData.getRejectReason());
        return Result.judge(result);
    }

    @Operation(summary = "单个报工单结算")
    @PostMapping("/{id}/settle")
    @PreAuthorize("@ss.hasPerm('factory:work-report:settle')")
    public Result<Void> settleWorkReport(
        @Parameter(description = "报工单ID") @PathVariable Long id
    ) {
        boolean result = workReportService.settleWorkReport(id);
        return Result.judge(result);
    }

    @Operation(summary = "批量结算报工单")
    @PostMapping("/batch-settle")
    @PreAuthorize("@ss.hasPerm('factory:work-report:settle')")
    public Result<Void> batchSettleWorkReports(
        @RequestBody @Validated BatchSettleForm formData
    ) {
        boolean result = workReportService.batchSettleWorkReports(formData.getIds());
        return Result.judge(result);
    }

    @Operation(summary = "获取当前用户指定月份的工资信息")
    @GetMapping("/monthly-salary")
    public Result<MonthlySalaryVO> getMonthlySalary(
        @Parameter(description = "月份（格式：yyyy-MM，例如：2019-12）") @RequestParam String month
    ) {
        MonthlySalaryVO result = workReportService.getMonthlySalary(month);
        return Result.success(result);
    }

    @Operation(summary = "获取所有员工指定月份的工资统计列表（老板核对工资用）")
    @GetMapping("/employee-salary-list")
    @PreAuthorize("@ss.hasPerm('factory:work-report:query')")
    public Result<List<EmployeeSalaryVO>> getEmployeeSalaryList(
        @Parameter(description = "月份（格式：yyyy-MM，例如：2025-10）") @RequestParam String month
    ) {
        List<EmployeeSalaryVO> result = workReportService.getEmployeeSalaryList(month);
        return Result.success(result);
    }

    @Operation(summary = "获取指定员工某月已审核通过的报工单分页列表")
    @GetMapping("/employee-month-report")
    @PreAuthorize("@ss.hasPerm('factory:work-report:query')")
    public PageResult<WorkReportVO> getEmployeeMonthWorkReportPage(WorkReportQuery queryParams) {
        IPage<WorkReportVO> result = workReportService.getEmployeeMonthWorkReportPage(queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "获取所有员工的工资发放状态列表")
    @GetMapping("/employee-payment-status")
    @PreAuthorize("@ss.hasPerm('factory:work-report:query')")
    public Result<List<EmployeePaymentStatusVO>> getEmployeePaymentStatusList(
        @Parameter(description = "月份（格式：yyyy-MM，例如：2025-10，不传则默认当前月份）") @RequestParam(required = false) String month
    ) {
        // 如果没有传月份，则默认使用当前月份
        if (month == null || month.isEmpty()) {
            month = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM"));
        }
        List<EmployeePaymentStatusVO> result = workReportService.getEmployeePaymentStatusList(month);
        return Result.success(result);
    }

    @Operation(summary = "发放工资（支持单个或批量）")
    @PostMapping("/pay-salary")
    @PreAuthorize("@ss.hasPerm('factory:work-report:edit')")
    public Result<Void> paySalary(@Validated @RequestBody PaySalaryForm form) {
        // 如果没有传月份，则默认使用当前月份
        String month = form.getPaymentMonth();
        if (month == null || month.isEmpty()) {
            month = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM"));
        }
        boolean result = salaryPaymentRecordService.paySalary(form.getEmployeeIds(), month);
        return result ? Result.success() : Result.failed("发放工资失败");
    }
}

/**
 * 批量审核表单
 */
@Getter
@Setter
class BatchAuditForm {
    @NotEmpty(message = "报工单ID列表不能为空")
    private List<Long> ids;
}

/**
 * 驳回表单
 */
@Getter
@Setter
class RejectForm {
    @NotBlank(message = "驳回原因不能为空")
    private String rejectReason;
}

/**
 * 批量驳回表单
 */
@Getter
@Setter
class BatchRejectForm {
    @NotEmpty(message = "报工单ID列表不能为空")
    private List<Long> ids;

    @NotBlank(message = "驳回原因不能为空")
    private String rejectReason;
}

/**
 * 批量结算表单
 */
@Getter
@Setter
class BatchSettleForm {
    @NotEmpty(message = "报工单ID列表不能为空")
    private List<Long> ids;
}

/**
 * 发放工资表单
 */
@Getter
@Setter
class PaySalaryForm {
    @NotEmpty(message = "员工ID列表不能为空")
    private List<Long> employeeIds;

    @Parameter(description = "发放月份（格式：yyyy-MM，例如：2025-10，不传则默认当前月份）")
    private String paymentMonth;
}
